package logic

// Logic 逻辑对象
type Logic struct {
	Items []Items
}

// New 新建逻辑对象
func New() *Logic {
	return &Logic{
		Facts: map[uint64]*Fact{},
	}
}

// Fact 事实定义
func (l *Logic) Fact(facts ...*Fact) *Logic {
	for _, f := range facts {
		l.Facts[f.ID] = f
	}
	l.analysis()
	return l
}

// And 事实定义
// name 关系或属性名称
// target 目标
// others 其他相关对象
func (l *Logic) And(name, target string, others ...string) *Logic {
	l.Fact(NewFact(And, name, target, others...))
	return l
}

// Rule 规则
func (l *Logic) Rule(rules ...*Rule) *Logic {
	l.Rules = append(l.Rules, rules...)
	l.analysis()
	return l
}
func (l *Logic) analysis() {
	for _, r := range l.Rules {
		// 根据规则事实查找所有备选事实
		// fs := []*Fact{}
		// for _, f := range r.Facts {
		// 	fs = append(fs, f.Filter(l.facts())...)
		// }
		// 生成符合规则的事实
		for _, f := range r.Filter(l.facts()) {
			l.Facts[f.ID] = f
		}
	}
}

// facts 事实
func (l *Logic) facts() []*Fact {
	fs := []*Fact{}
	for _, f := range l.Facts {
		fs = append(fs, f)
	}
	return fs
}

// Assert 断言
func (l *Logic) Assert(name, target string, others ...string) bool {
	for _, f := range l.Facts {
		if f.Name == name && f.Target == target && arrayEqual(f.Others, others) {
			return true
		}
	}
	return false
}

// Queries 查询
func (l *Logic) Queries(name, target string, others ...string) []Answer {
	ret := []Answer{}
	if isVar(target) {
		// 求值
		for _, f := range l.Facts {
			if f.Name == name && arrayEqual(f.Others, others) {
				ret = append(ret, Answer{Var: target, Str: f.Target})
			}
		}
	} else {
		// 列表
		for _, f := range l.Facts {
			if f.Name == name && target == f.Target {
				ret = append(ret, arrayAnswer(f.Others, others)...)
			}
		}
	}
	return ret
}

// Listing 列出事实
func (l *Logic) Listing(name string) []*Fact {
	ret := []*Fact{}
	for _, f := range l.Facts {
		if f.Name == name {
			ret = append(ret, f)
		}
	}
	return ret
}
